using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using BSDS.Core.Model;
using BSDS.Core.Model.Data;
using BSDS.Core.Model.Conversion;

namespace BSDS.Core.Data.Local.Csv.Parsing
{
    public class CsvFormatParser : IParser
    {
        private readonly CsvAttributeInfoParser attributeParser;
        private readonly CsvEntityParser entityParser;

        private readonly DataFormat dataFormat;
        

        public CsvFormatParser(DataFormat dataFormat)
        {
            this.dataFormat = dataFormat;
            
            attributeParser = new CsvAttributeInfoParser();
            entityParser = new CsvEntityParser();
        }

        public BsdsData Parse(string filename, FormatConvertMode convertMode )
        {
            using (var inputStream = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.Read)))
            {
                var entityValues = new List<EntityValue>();

                var firstLine = inputStream.ReadLine();

                if (firstLine != null)
                {
                    // The line which reads "Bing Spatial Data Services, 1.0, <entity type name>" is optional for the BSDS tool. Skip it if found.
                    var BingSDSheader = firstLine.Split(',');
                    if (BingSDSheader[0].Trim() == "Bing Spatial Data Services")
                        firstLine = inputStream.ReadLine();

                    if (firstLine != null)
                    {
                        var separator = CsvType.Parse(dataFormat.Value).Separator;
                        var splitter = new[] { separator.Value };

                        AttributeInfo[] attributeInfos = null;

                        switch (convertMode)
                        {
                            case FormatConvertMode.ConvertFromMappoint:
                                attributeInfos = firstLine.Split(splitter, StringSplitOptions.None).Select(attributeParser.FromMappointCSV).ToArray();
                                break;
                            case FormatConvertMode.ConvertFromMultimap:
                                attributeInfos = firstLine.Split(splitter, StringSplitOptions.None).Select(attributeParser.FromMultimapCSV).ToArray();
                                break;
                            default:
                                attributeInfos = firstLine.Split(splitter, StringSplitOptions.None).Select(attributeParser.FromCsv).ToArray();
                                break;
                        }

                        while (!inputStream.EndOfStream)
                        {
                            entityValues.Add(entityParser.FromCsv(attributeInfos, inputStream.ReadLine(), separator));
                        }
                    }
                }

                return new BsdsData(entityValues.ToArray(), filename, dataFormat, "BSDSEntity");
            }
        }
    }
}